perm filename PROGS.PAL[11,HE]1 blob sn#615932 filedate 1981-10-06 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00008 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00002 00002	Program to copy a disk image to & from the 10		DCOPY.PAL
C00015 00003							BOOT.PAL
C00016 00004							BOOT2.PAL
C00017 00005	Program to test out the DR11-C				DR11C.PAL
C00025 00006								DZ11.PAL
C00027 00007	Program to talk to one of the PUMA's with the VT05		PUMA.PAL
C00031 00008	Program to test out communication with the Vision Module via the DR11-C
C00048 ENDMK
C⊗;
;Program to copy a disk image to & from the 10		DCOPY.PAL

.INSRT STUFF.PAL[11,ARG]

BUF1 = 10000
BUF2 = 40000

.=1000
BUFPT:	0			;Where the 10 will look for the disk buffer
DRVNUM:	0			;Which disk drive we're to use
DOIT:	0			;Set when drive number is valid

START:	RESET
	MOV #1000,SP		;Set up the stack
	MOV #BEGMES,R1		;Tell world who we are
	JSR PC,OUTSTR
	MOV #CRLF,R1
	JSR PC,OUTSTR
	CLR DOIT

LOOP:	CLR BUFPT
1$:	TST DOIT		;Wait until 10's ready
	BEQ 1$
	MOV DRVNUM,R0		;Get desired drive #
	BIC #177774,R0
	ASH #13.,R0		;Shift drive # to high order bits
2$:	TSTB RKCS		;Make sure drive is ready
	BPL 2$			; Nope - keep waiting
	MOV R0,RKDA		;Select drive, cyl 0, surface 0, sector 0
	MOV DOIT,R0		;See whether we're reading or writing
	CLR DOIT
	CMP #1,R0		;Reading?
	BEQ READ		; Yes
	JMP WRITE		; No

READ:	MOV RKDA,R2		;Save Disk address register
	MOV #BUF1,RKBA		;Fill up both buffers
	MOV #-30000,RKWC	;Set word count
	MOV #5,RKCS		;Go read in the first two cylinders
1$:	TSTB RKCS		;Wait for disk operation to finished
	BPL 1$			; Nope - keep waiting
	TST RKCS		;See that last operation didn't cause an error
	BPL 2$			; Skip ahead if everything's ok
	MOV #1,BUFPT		;Tell 10 we had an error
	MOV #ERRMES,R1		;Complain about it too
	JSR PC,OUTSTR
	MOV #CRLF,R1
	JSR PC,OUTSTR
	BPT			;Punt
2$:	MOV #BUF1,RKBA		;Now let's confirm that the read was ok
	MOV R2,RKDA		;Restore old disk address register
	MOV #-30000,RKWC	;Set word count
	MOV #13,RKCS		;Go read check the first two cylinders
3$:	TSTB RKCS		;Wait for disk operation to finish
	BPL 3$			; Nope - keep waiting
	MOV #201.,R5		;# of cylinders more to read
	MOV #BUF1,BUFPT		;Tell 10 data's ready for it now

RLOOP:	TST BUFPT		;Wait til 10's done with buffer
	BNE RLOOP
1$:	TSTB RKCS		;See if last disk operation has finished
	BPL 1$			; Nope - wait
	TST RKCS		;See that last operation didn't cause an error
	BPL 3$			; Skip ahead if everything's ok
2$:	MOV #1,BUFPT		;Tell 10 we had an error
	MOV #ERRMES,R1		;Complain about it too
	JSR PC,OUTSTR
	MOV #CRLF,R1
	JSR PC,OUTSTR
	BPT			;Punt
3$:	MOV #BUF2,BUFPT		;Start 10 on 2nd buffer while we refill 1st
	MOV #BUF1,R4
	MOV R4,RKBA		;Filling up buffer 1
	MOV RKDA,R2		;Save Disk address register
	MOV #-14000,RKWC	;Set word count
	MOV #5,RKCS		;Go read in the next cylinder
4$:	TSTB RKCS		;Wait for disk operation to finish
	BPL 4$			; Nope - keep waiting
	TST RKCS		;See that last operation didn't cause an error
	BMI 2$			; Complain if it did
	MOV #BUF1,RKBA		;Now let's confirm that the read was ok
	MOV R2,RKDA		;Restore old disk address register
	MOV #-14000,RKWC	;Set word count
	MOV #13,RKCS		;Go read check the cylinder
	DEC R5			;Check if that's the last one
	BEQ RLBUF		; & get ready to quit of so

RB2LP:	TST BUFPT		;Wait til 10's done with second buffer
	BNE RB2LP
1$:	TSTB RKCS		;See if last disk operation has finished
	BPL 1$			; Nope - wait
	TST RKCS		;See that last operation didn't cause an error
	BPL 3$			; Skip ahead if everything's ok
2$:	MOV #1,BUFPT		;Tell 10 we had an error
	MOV #ERRMES,R1		;Complain about it too
	JSR PC,OUTSTR
	MOV #CRLF,R1
	JSR PC,OUTSTR
	BPT			;Punt
3$:	MOV #BUF1,BUFPT		;Start 10 on 1st buffer while we refill 2nd
	MOV RKDA,R2		;Save Disk address register
	MOV #BUF2,R4
	MOV R4,RKBA		;Filling up buffer 2
	MOV #-14000,RKWC	;Set word count
	MOV #5,RKCS		;Go read in the next cylinder
4$:	TSTB RKCS		;Wait for disk operation to finish
	BPL 4$			; Nope - keep waiting
	TST RKCS		;See that last operation didn't cause an error
	BMI 2$			; Complain if it did
	MOV #BUF2,RKBA		;Now let's confirm that the read was ok
	MOV R2,RKDA		;Restore old disk address register
	MOV #-14000,RKWC	;Set word count
	MOV #13,RKCS		;Go read check the cylinder
	DEC R5			;Check if more cylinders to be read
	BNE RLOOP

RLBUF:	TST BUFPT		;Wait til 10's done with previous buffer
	BNE RLBUF
1$:	TSTB RKCS		;See if disk operation has finished
	BPL 1$			; Nope - wait
	TST RKCS		;See that last operation didn't cause an error
	BPL 2$			; Skip ahead if everything's ok
	MOV #1,BUFPT		;Tell 10 we had an error
	MOV #ERRMES,R1		;Complain about it too
	JSR PC,OUTSTR
	MOV #CRLF,R1
	JSR PC,OUTSTR
	BPT			;Punt
2$:	MOV R4,BUFPT		;Start 10 on last buffer
3$:	TST BUFPT		;Wait til 10's done with buffer
	BNE 3$
	JMP LOOP		;We're all done now

WRITE:	MOV #BUF1,BUFPT		;Tell 10 to start filling buffer 1
	MOV #203.,R5		;# of cylinders we'll be writing
	MOV #11,RKCS		;Do a seek operation to get ready

WLOOP:	TST BUFPT		;Wait til 10's done with buffer
	BNE WLOOP
1$:	TSTB RKCS		;See if last disk operation has finished
	BPL 1$			; Nope - wait
	TST RKCS		;See that last operation didn't cause an error
	BPL 3$			; Skip ahead if everything's ok
2$:	MOV #1,BUFPT		;Tell 10 we had an error
	MOV #ERRMES,R1		;Complain about it too
	JSR PC,OUTSTR
	MOV #CRLF,R1
	JSR PC,OUTSTR
	BPT			;Punt
3$:	MOV #BUF2,BUFPT		;Start 10 on 2nd buffer while we empty 1st
	MOV RKDA,R2		;Save Disk address register
	MOV #BUF1,RKBA		;Writing out buffer 1
	MOV #-14000,RKWC	;Set word count
	MOV #3,RKCS		;Go write out the next cylinder
4$:	TSTB RKCS		;Wait for disk operation to finish
	BPL 4$			; Nope - keep waiting
	TST RKCS		;See that last operation didn't cause an error
	BMI 2$			; Complain if it did
	MOV #BUF1,RKBA		;Now let's confirm that the write was ok
	MOV R2,RKDA		;Restore old disk address register
	MOV #-14000,RKWC	;Set word count
	MOV #7,RKCS		;Go write check the cylinder
	DEC R5			;Check if that's the last one
	BEQ WLBUF		; Yup go quit

WB2LP:	TST BUFPT		;Wait til 10's done with second buffer
	BNE WB2LP
1$:	TSTB RKCS		;See if last disk operation has finished
	BPL 1$			; Nope - wait
	TST RKCS		;See that last operation didn't cause an error
	BPL 3$			; Skip ahead if everything's ok
2$:	MOV #1,BUFPT		;Tell 10 we had an error
	MOV #ERRMES,R1		;Complain about it too
	JSR PC,OUTSTR
	MOV #CRLF,R1
	JSR PC,OUTSTR
	BPT			;Punt
3$:	MOV #BUF1,BUFPT		;Start 10 on 1st buffer while we empty 2nd
	MOV RKDA,R2		;Save Disk address register
	MOV #BUF2,RKBA		;Writing out buffer 2
	MOV #-14000,RKWC	;Set word count
	MOV #3,RKCS		;Go write out the next cylinder
4$:	TSTB RKCS		;Wait for disk operation to finish
	BPL 4$			; Nope - keep waiting
	TST RKCS		;See that last operation didn't cause an error
	BMI 3$			; Complain if it did
	MOV #BUF2,RKBA		;Now let's confirm that the write was ok
	MOV R2,RKDA		;Restore old disk address register
	MOV #-14000,RKWC	;Set word count
	MOV #7,RKCS		;Go write check the cylinder
	DEC R5			;Check if that's the last one
	BNE WLOOP		; Nope - keep going

WLBUF:	TST BUFPT		;Wait til 10's done with previous buffer
	BNE WLBUF
1$:	TSTB RKCS		;Wait for disk operation to finish
	BPL 1$			; Nope - keep waiting
	TST RKCS		;See that last operation didn't cause an error
	BPL 2$			; Skip ahead if everything's ok
	MOV #1,BUFPT		;Tell 10 we had an error
	MOV #ERRMES,R1		;Complain about it too
	JSR PC,OUTSTR
	MOV #CRLF,R1
	JSR PC,OUTSTR
	BPT			;Punt
2$:	MOV #2,BUFPT		;Tell 10 last buffer was okay
3$:	TST BUFPT		;Wait til 10's done with buffer
	BNE 3$
	JMP LOOP		;We're all done now

;VT05 I/O routines

OUTSTR:	MOVB (R1)+,R0		;Get next char
	BEQ 1$			;If done - quit
	JSR PC,OUTCHR		;Print it
	BR OUTSTR
1$:	JSR PC,OUTCHR		;Print a couple nulls
	JSR PC,OUTCHR
;	JMP OUTCHR

OUTCHR:	TST OUTSW		;Who does it go to?
	BEQ 2$
1$:	TSTB KBOS		;VT05 ready?
	BPL 1$			;Loop til it is
	MOVB R0,KBOR		;Print the char
	RTS PC
2$:	TSTB OREG		;Console ready?
	BNE 2$			;Wait til it is
	MOVB R0,OREG		;Output char
	RTS PC

INCHR:	TST OUTSW		;Where does it come from?
	BEQ 1$
	TSTB KBIS		;Anything typed on VT05?
	BPL 2$			; No
	MOVB KBIR,R0		; Read the char
	RTS PC
1$:	TSTB IREG		;Anything from the 10?
	BEQ 2$			; No
	MOVB IREG,R0		; Fetch the char
	CLRB IREG
	RTS PC
2$:	CLR R0			;No input
	RTS PC

;Data & Constants

BEGMES:	.ASCII /πDisk Copy Program/
CRLF:	.BYTE 12,15,0
ERRMES: .ASCIZ /πDisk Errorπ/

.END START
;						BOOT.PAL
.=1000

START:	MOV #177406,%0		;ADDR WORD COUNT REG
	MOV #177400,(%0)	;READ 400 WDS
;	MOV #40000,4(%0)	;USE DRIVE 2 (60000 FOR 3, 20000 FOR 1)
	MOV #5,-(%0)		;GO READ
1$:	TSTB (%0)		;WAIT TIL DONE
	BPL 1$
	CLR %7			;JUMP TO BOOTSTRAP AT LOC 0

.END START
;						BOOT2.PAL
.=1000

START:	MOV #177406,%0		;ADDR WORD COUNT REG
	MOV #177400,(%0)	;READ 400 WDS
	MOV #40000,4(%0)	;USE DRIVE 2 (60000 FOR 3, 20000 FOR 1)
	MOV #5,-(%0)		;GO READ
1$:	TSTB (%0)		;WAIT TIL DONE
	BPL 1$
	CLR %7			;JUMP TO BOOTSTRAP AT LOC 0

.END START
;Program to test out the DR11-C				DR11C.PAL

.INSRT STUFF.PAL[11,ARG]

;DR11-C definitions

DRCSR  = 763770		;Control and Status register
DROBUF = 763772		;Output Buffer register
DRIBUF = 763774		;Input Buffer register

DRIVEC = 340		;Request A & B interrupt vectors

.=DRIVEC
DRINTA			;Req A interrupt handler
240			;Level 5
DRINTB			;Req B interrupt handler
240			;Level 5


.=1000

START:	RESET
	MOV #START,SP		;Set up the stack
	MOV #BEGMES,R1		;Tell world who we are
	JSR PC,OUTSTR
	MOV #CRLF,R1
	JSR PC,OUTSTR
	CLR %PS			;Priority level 0
	MOV #DRINTA,DRIVEC	;Set up interrupt vectors
	MOV #DRINTB,DRIVEC+4
	MOV #140,DRCSR		;Enable interrupts
	MOV #RAMES,R1		;Ready to cause a Req A interrupt
	JSR PC,OUTSTR
	MOV #CRLF,R1
	JSR PC,OUTSTR
	CLR ADONE
	BIS #1,DRCSR		;Set CSR0 = Req A
1$:	TST ADONE
	BEQ 1$			;Wait around until interrupt handled

	MOV #NOIMES,R1		;Ready to not cause another one
	JSR PC,OUTSTR
	MOV #CRLF,R1
	JSR PC,OUTSTR
	CLR ADONE
	MOV #100,R4
	BIS #1,DRCSR		;Set CSR0 = Req A
2$:	TST ADONE
	BNE TB			;Was interrupt handled?
	SOB R4,2$		;Wait a little bit

TB:	MOV #RBMES,R1		;Ready to cause a Req B interrupt
	JSR PC,OUTSTR
	MOV #CRLF,R1
	JSR PC,OUTSTR
	CLR BDONE
	BIS #2,DRCSR		;Set CSR1 = Req B
1$:	TST BDONE
	BEQ 1$			;Wait around until interrupt handled

	MOV #NOIMES,R1		;Ready to not cause another one
	JSR PC,OUTSTR
	MOV #CRLF,R1
	JSR PC,OUTSTR
	CLR BDONE
	MOV #100,R4
	BIS #2,DRCSR		;Set CSR1 = Req B
2$:	TST BDONE
	BNE BOTH		;Was interrupt handled?
	SOB R4,2$		;Wait a little bit

BOTH:	MOV #BIMES,R1		;Ready to cause both
	JSR PC,OUTSTR
	MOV #CRLF,R1
	JSR PC,OUTSTR
	CLR BDONE
	CLR ADONE
	MOV #100,R4
	BIC #3,DRCSR		;Get ready to interrupt both
	BIS #3,DRCSR		;Set CSR0 & CSR1 = Req A & B
1$:	MOV BDONE,R0
	ADD ADONE,R0
	CMP R0,#2
	BGE SEND		;Both interrupts handled?
	SOB R4,1$		;Wait a little bit more if need be

SEND:	MOV #SNDMES,R1		;Ready to send a message
	JSR PC,OUTSTR
	MOV #CRLF,R1
	JSR PC,OUTSTR
	MOV #OBUF,OPTR		;Set up things for sending a message
	MOV #10,OCNT
	MOV #IBUF,IPTR
	MOV #10,ICNT
	MOV #RCVR,DRIVEC	;Set up interrupt vctors
	MOV #SNDR,DRIVEC+4
	CLR MDONE
	BIC #3,DRCSR		;Clear old interrupts
	BIS #2,DRCSR		;Start up the send routine
1$:	TST MDONE
	BEQ 1$			;Wait for it to finish
	MOV #RCVMES,R1		;All done with it
	JSR PC,OUTSTR
	MOV #CRLF,R1
	JSR PC,OUTSTR
	BPT
	JMP START

;Various interrupt routines

DRINTA: CLR R0
1$:	DEC R0
	BNE 1$			;Kill some time
	MOV #AMES,R1		;Tell world who we are
	JSR PC,OUTSTR
	MOV #CRLF,R1
	JSR PC,OUTSTR
	CLR R0
2$:	DEC R0
	BNE 2$			;Kill some more time
	INC ADONE
	RTI			;All done here

DRINTB: CLR R0
1$:	DEC R0
	BNE 1$			;Kill some time
	MOV #BMES,R1		;Tell world who we are
	JSR PC,OUTSTR
	MOV #CRLF,R1
	JSR PC,OUTSTR
	CLR R0
2$:	DEC R0
	BNE 2$			;Kill some more time
	INC BDONE
	RTI			;All done here


;Now let's get serious

SNDR:	BIC #3,DRCSR		;Turn off interrupts
	DEC OCNT		;Any more?
	BLT 1$			; no
	MOV @OPTR,DROBUF	;Get next word to send
	ADD #2,OPTR
	INC DRCSR		;Set CSR0 = Req A
1$:	RTI

RCVR:	BIC #3,DRCSR		;Turn off interrupts
	DEC ICNT		;Any more?
	BGT 1$			; yes
	INC MDONE		; no - indicate all done
	BR 2$
1$:	MOV DRIBUF,@IPTR	;Get next word
	ADD #2,IPTR
	BIS #2,DRCSR		;Ready for next - set CSR1 = Req B
2$:	RTI

;VT05 I/O routines

OUTSTR:	MOVB (R1)+,R0		;Get next char
	BEQ 1$			;If done - quit
	JSR PC,OUTCHR		;Print it
	BR OUTSTR
1$:	JSR PC,OUTCHR		;Print a couple nulls
	JSR PC,OUTCHR
;	JMP OUTCHR

OUTCHR:	TST OUTSW		;Who does it go to?
	BEQ 2$
1$:	TSTB KBOS		;VT05 ready?
	BPL 1$			;Loop til it is
	MOVB R0,KBOR		;Print the char
	RTS PC
2$:	TSTB OREG		;Console ready?
	BNE 2$			;Wait til it is
	MOVB R0,OREG		;Output char
	RTS PC

INCHR:	TST OUTSW		;Where does it come from?
	BEQ 1$
	TSTB KBIS		;Anything typed on VT05?
	BPL 2$			; No
	MOVB KBIR,R0		; Read the char
	RTS PC
1$:	TSTB IREG		;Anything from the 10?
	BEQ 2$			; No
	MOVB IREG,R0		; Fetch the char
	CLRB IREG
	RTS PC
2$:	CLR R0			;No input
	RTS PC

;Data & Constants

OBUF:	.WORD 1,2,3,4,5,6,7,10	;Message to send
	.BLKW 20
IBUF:	.BLKW 40		;Where we'll store the message

OPTR:	OBUF		;What to send next
OCNT:	10		;How much left to send
IPTR:	IBUF		;Where to store next word
ICNT:	10		;How much left to receive

ADONE: 	.WORD 0		;Set by DRINTA interrupt routine
BDONE: 	.WORD 0		;Set by DRINTB interrupt routine
MDONE: 	.WORD 0		;Set when message has been sent

BEGMES:	.ASCII /πDR11-C Test Program/
CRLF:	.BYTE 12,15,0
RAMES:	.ASCIZ /πReady to generate an A interrupt/
RBMES:	.ASCIZ /πReady to generate a B interrupt/
BIMES:	.ASCIZ /πReady to generate both A & B interrupts/
NOIMES:	.ASCIZ /π... but this shouldn't/
AMES:	.ASCIZ /π - Handling an A request - /
BMES:	.ASCIZ /π - Handling a B request - /
SNDMES:	.ASCIZ /πSending a little message . . . /
RCVMES: .ASCIZ /πAll done now./


.END START
;							DZ11.PAL
.INSRT STUFF.PAL[11,ARG]

;DZ11 definitions

DZCSR  = 160000		;Control and Status register
DZLPR  = 160002		;Line Parameter register      (write only)
DZRBUF = 160002		;Receiver Buffer register     (read  only)
DZTCR  = 160004		;Transmitter Control register (byte)
DZTBUF = 160006		;Transmitter Buffer	      (byte, write only)

.=1000

START:	RESET
	MOV #START,SP		;Set up the stack
	BIS #40,DZCSR		;Turn on master scan enable
ZERO:	MOV #10,R0
	MOV #LINE,R1
1$:	CLR (R1)+
	SOB R0,1$
TEST:	MOV #1000,R0
2$:	MOV DZRBUF,R1
	SWAB R1
	BIC #177770,R1
	ASL R1
	INC LINE(R1)
	SOB R0,2$
FIN:	BPT
	BPT

LINE:	.WORD 0,0,0,0,0,0,0,0

.END START
;Program to talk to one of the PUMA's with the VT05		PUMA.PAL

.INSRT STUFF.PAL[11,ARG]

;DZ11 definitions

DZCSR  = 160000		;Control and Status register
DZLPR  = 160002		;Line Parameter register      (write only)
DZRBUF = 160002		;Receiver Buffer register     (read  only)
DZTCR  = 160004		;Transmitter Control register (byte)
DZTBUF = 160006		;Transmitter Buffer	      (byte, write only)

.=1000

START:	RESET
	MOV #START,SP		;Set up the stack
	MOV #BEGMES,R1		;Tell world who we are
	JSR PC,OUTSTR
	MOV #CRLF,R1
	JSR PC,OUTSTR

;Set up the DZ11 using line # in LINE

	MOV #13430,R0		;line parameters: 1200 baud, 8 char, no parity
	BIS LINE,R0		;Choose which line
	MOV R0,DZLPR		;Tell DZ11 what parameters to use
	MOV #1,R0
	ASH LINE,R0		;Set up transmit bit for line we're using
	MOVB R0,DZTCR		;Turn on transmit for line
	BIS #40,DZCSR		;Turn on master scan enable

;Now talk

TLOOP:	JSR PC,INCHR		;Any input - returned in R0
	TST R0
	BEQ 2$			; No - go check if anything to print

	CMP #3,R0		;Was it a ↑C? (Do we really want this?)
	BNE 1$			; No
	BPT			; Yes - break to DDT
	BR 2$			; Proceeding will just continue

1$:	TST DZCSR		;Can we send it yet?
	BPL 1$			; No - wait til we can (This may not work)
	MOVB R0,DZTBUF		;Send input char over

2$:	MOV DZRBUF,R0		;See if anything to output
	BPL TLOOP		; No
	JSR PC,OUTCHR		; Yes - print it
	BR TLOOP		;Do it all again


;VT05 I/O routines

OUTSTR:	MOVB (R1)+,R0		;Get next char
	BEQ 1$			;If done - quit
	JSR PC,OUTCHR		;Print it
	BR OUTSTR
1$:	JSR PC,OUTCHR		;Print a couple nulls
	JSR PC,OUTCHR
;	JMP OUTCHR

OUTCHR:	TST OUTSW		;Who does it go to?
	BEQ 2$
1$:	TSTB KBOS		;VT05 ready?
	BPL 1$			;Loop til it is
	MOVB R0,KBOR		;Print the char
	RTS PC
2$:	TSTB OREG		;Console ready?
	BNE 2$			;Wait til it is
	MOVB R0,OREG		;Output char
	RTS PC

INCHR:	TST OUTSW		;Where does it come from?
	BEQ 1$
	TSTB KBIS		;Anything typed on VT05?
	BPL 2$			; No
	MOVB KBIR,R0		; Read the char
	RTS PC
1$:	TSTB IREG		;Anything from the 10?
	BEQ 2$			; No
	MOVB IREG,R0		; Fetch the char
	CLRB IREG
	RTS PC
2$:	CLR R0			;No input
	RTS PC

;Data & Constants

LINE: 	.WORD 1		;Which DZ11 line we are using

BEGMES:	.ASCII /πPuma terminal program/
CRLF:	.BYTE 12,15,0

.END START
;Program to test out communication with the Vision Module via the DR11-C
;								VMTST.PAL
.INSRT STUFF.PAL[11,ARG]

; COMMANDS are:
	TRANS=	040000		; TRANSFER DATA COMMAND
	ERESET=	140000		; RESET
	ERESAK=	160000		; RESET ACKNOWLEDGE

; STATUS word values are:
;	OK=	0		; DONE WITH A CLR
	ERBUF0=	101000		; NO BUFFERS AVAILABLE FOR INPUT MESSAGE
	ERBUFS=	102000		; NEXT BUFFER IS TOO SMALL
	ERCHKS=	103000		; CHECKSUM ERROR

;DR11-C definitions

DRCSR  = 763770		;Control and Status register
DROBUF = 763772		;Output Buffer register
DRIBUF = 763774		;Input Buffer register

DRIVEC = 340		;Request A & B interrupt vectors

.=DRIVEC
DRINTA			;Req A interrupt handler
240			;Level 5
DRINTB			;Req B interrupt handler
240			;Level 5


.=1000

START:	RESET
	MOV #START,SP		;Set up the stack
	MOV #BEGMES,R1		;Tell world who we are
	JSR PC,OUTSTR
	MOV #CRLF,R1
	JSR PC,OUTSTR
	CLR %PS			;Priority level 0

;Initialize the DR11-C link

	MOV #DRINTA,DRIVEC	;Set up interrupt vectors
	MOV #DRINTB,DRIVEC+4
	CLR STATE		;We're not doing anything yet
	MOV #140,DRCSR		;Enable interrupts

;See if anyone's home

	MOV #6,STATE		;Send a RESET & see if it gets acknowledged
	MOV #ERESET,DROBUF
	INC DRCSR		;Int A in VM

	MOV #100,R1		;Now wait a while for the reset acknowledge
1$:	CLR R0
2$:	TST STATE
	BEQ 3$			;STATE will be set to 0 when we get the resak
	SOB R0,2$
	SOB R1,1$

	MOV #TIMMES,R1		;Time out
	JSR PC,OUTSTR
	MOV #CRLF,R1
	JSR PC,OUTSTR
	BPT
	BR START		;Try again

3$:	BIS #2,DRCSR		;Set CSR 1 for "B" response (may not be needed)

;Mini test loop

TLOOP:	MOV #RDYMES,R1		;Ready to send a message over
	JSR PC,OUTSTR
	MOV #CRLF,R1
	JSR PC,OUTSTR
	BPT
	CLR CKSUM
	MOV MESS,R0		;R0 ← address of message to send
	MOV (R0)+,R1		;R1 ← Message length in bytes
	MOV R1,R2
	INC R2			;In case odd number of bytes
	ASR R2			;Convert bytes → word count
	MOV R2,SCNT		;Set up word count
	MOV R0,SPTR		;Set up pointer at message
	MOV #RBUF,RPTR		;Reset receive message pointer
	BIS #TRANS,R1		;R1 ← Send command bits + byte count
	MOV R1,DROBUF		;Get ready to send it
	BIC #3,DRCSR		;Clear CSR 0 & 1 bits
	MOV #1,STATE
	CLR SDONE
	CLR RDONE
	MOV #TSNMES,R1		;Say we're trying to send it now
	JSR PC,OUTSTR
	INC DRCSR		;"A" Request for command

1$:	TST SDONE		;Wait for it to have been sent
	BEQ 1$
	MOV #TRCMES,R1		;Now we want to receive the VM's reply
	JSR PC,OUTSTR
2$:	TST RDONE		;Wait for it to have been received
	BEQ 2$
	MOV #DONMES,R1		;Done - now we can look at the VM's reply
	JSR PC,OUTSTR
	MOV #CRLF,R1
	JSR PC,OUTSTR
	BR TLOOP		;Ready to do it all again

;Interrupt routines

DRINTA:	MOV R0,-(SP)
	MOV #ADISP,R0		;Use A dispatch table
	BR DRINT
DRINTB:	MOV R0,-(SP)
	MOV #BDISP,R0		;Use B dispatch table
DRINT:	MOV R1,-(SP)
	MOV R2,-(SP)
	MOV R3,-(SP)
	BIC #3,DRCSR		;Clear interrupt requests
	MOV DRIBUF,R3		;R3 ← Anything sent over to us
	ADD STATE,R0
	ADD STATE,R0		;Get offset into dispatch table
	JMP @0(R0)			;Go do it

INTRB:	BIS #2,DRCSR		;Signal with a B request
INTRET:	MOV (SP)+,R3
	MOV (SP)+,R2
	MOV (SP)+,R1
	MOV (SP)+,R0
	RTI

;Sending routines

; In case he's not ready to start receiving when we want to send

A1:	BIC #777,R3		;Clear all non-status bits
	CLR STATE		;So we can receive
	CMP #ERBUF0,R3		;No buffers error?
	BNE 2$
	MOV #NBFMES,R1
1$:	JSR PC,OUTSTR
	MOV #CRLF,R1
	JSR PC,OUTSTR
	BPT
	BR INTRB
2$:	CMP #ERBUFS,R3		;Buffer too small?
	BNE 3$
	MOV #SBFMES,R1
	BR 1$
3$:	CMP #ERESET,R3		;External Reset?
	BNE 4$
	MOV #ERESAK,DROBUF	;Send a reset acknowledge
	INC DRCSR		;Int A
	MOV #RESMES,R1
	BR 1$
4$:	MOV #ERRMES,R1
	BR 1$

;It's okay with him to send - ship it over

B1:	INC STATE
	MOV #SNDMES,R1		;Say we're sending it now
	JSR PC,OUTSTR
B2:	DEC SCNT		;More to send?
	BPL 1$			; yes - do it
	MOV CKSUM,DROBUF	; no - go send cksum
	INC STATE		; Update state
	BR INTRB		; B Req & return
1$:	MOV @SPTR,R0		;Fetch next word to send
	XOR R0,CKSUM		;Update check sum
	MOV R0,DROBUF		;Move it to output buffer
	ADD #2,SPTR		;Bump pointer
	BR INTRB		;B Req & return

;Done sending - see if he received it okay

A3:	TST R3			;Check status
	BMI 1$			; Error skip ahead
	CLR STATE		;Done here
	INC SDONE
	BR INTRB		;B Req & return so VM can continue

1$:	CMP #ERESET,R3		;Remote Reset?
	BNE 2$			; no
	MOV #ERESAK,DROBUF	;Send a reset acknowledge
	INC DRCSR		;Int A
	MOV #RESMES,R1
	BR 3$
2$:	MOV #CHKMES,R1		;Must be a checksum error
3$:	JSR PC,OUTSTR
	MOV #CRLF,R1
	JSR PC,OUTSTR
	BPT
	CLR CKSUM
	MOV MESS,R0		;R0 ← address of message to send
	MOV (R0)+,R1		;R1 ← Message length in bytes
	MOV R1,R2
	INC R2			;In case odd number of bytes
	ASR R2			;Convert bytes → word count
	MOV R2,SCNT		;Set up word count
	MOV R0,SPTR		;Set up pointer at message
	BIS #TRANS,R1		;R1 ← Send command bits + byte count
	MOV R1,DROBUF		;Get ready to send it
	BIC #3,DRCSR		;Clear CSR 0 & 1 bits
	MOV #1,STATE
	CLR SDONE
	CLR RDONE
	MOV #RSDMES,R1		;Say we're sending it now
	JSR PC,OUTSTR
	INC DRCSR		;"A" Request for command
	BR INTRET		;Return from interrupt

;Receiving routines

;Ready to start receiving

A0:	TST R3			;See if transfer request
	BGT 3$			; yes - skip ahead & do it
	BIC #17777,R3		;Clear all except command bits
	BNE 1$
	JMP INTRB		;Null status - just ignore
1$:	CMP #ERESET,R3		;Make sure it was a reset
	BNE 2$
	MOV #ERESAK,DROBUF	;Send a reset acknowledge
	INC DRCSR		;Int A & return
	JMP INTRET
2$:	MOV #ERRMES,R1		;What's going on?
	JSR PC,OUTSTR
	MOV #CRLF,R1
	JSR PC,OUTSTR
	BPT
	MOV #ERESET,DROBUF	;Try to reset things
	INC DRCSR
	MOV #6,STATE		;Wait for reset acknowledgement
	JMP INTRET

3$:	BIC #TRANS,R3		;Clear command bits
	MOV R3,@RPTR		;Store byte count
	ADD #2,RPTR
	INC R3			;In case odd number of bytes
	ASR R3			;Convert bytes to words
	MOV R3,RCNT		;Store it
	CLR CKSUM
	MOV #4,STATE		;Receive data
	MOV #RCVMES,R1		;Say that we're receiving
	JSR PC,OUTSTR
	JMP INTRB		;B response & return

;Store the message away now

B4:	DEC RCNT		;More to message?
	BMI 1$			; no - go get checksum
	MOV R3,@RPTR		;Store data away
	ADD #2,RPTR
	XOR R3,CKSUM		;Accumulate checksum
	JMP INTRB		;B response & return

1$:	CMP R3,CKSUM		;Checksum okay
	BNE 2$			; No
	INC STATE		; Yes - send ok status & wait til ok to proceed
	CLR DROBUF
	INC DRCSR		;A response & return
	JMP INTRET

2$:	MOV #CHKMES,R1		;Checksum error
	JSR PC,OUTSTR
	MOV #CRLF,R1
	JSR PC,OUTSTR
	MOV #RRCMES,R1		;Request retransmission
	JSR PC,OUTSTR
	CLR STATE
	MOV #ERCHKS,DROBUF
	INC DRCSR		;Req A
	JMP INTRET

;Done receiving

B5:	INC RDONE		;Let everyone know that we're done
	CLR STATE
	JMP INTRET

;Reset & bad requests


;Waiting for Reset Acknowledgement

A6:	BIC #17777,R3		;Strip to command bits
	CMP #ERESET,R3		;Check for VM reseting also
	BNE 2$			; no
	MOV #ERESAK,DROBUF	; yes - acknowledge his
	INC DRCSR		;Req A & return
1$:	JMP INTRET
2$:	CMP #ERESAK,R3		;Is VM acknowledging us?
	BNE 1$			; no - ignore it
	CLR STATE		; yes - ok
	JMP INTRB		;B response & return

;Ignore Req B's

B0:	JMP INTRET

;Bad Requests

ABAD:	MOV #ABDMES,R1		;Complain
	BR BAD1
BBAD:	MOV #BBDMES,R1		;Complain
BAD1:	JSR PC,OUTSTR
	MOV #CRLF,R1
	JSR PC,OUTSTR
	BPT
	JMP INTRET

;VT05 I/O routines

OUTSTR:	MOVB (R1)+,R0		;Get next char
	BEQ 1$			;If done - quit
	JSR PC,OUTCHR		;Print it
	BR OUTSTR
1$:	JSR PC,OUTCHR		;Print a couple nulls
	JSR PC,OUTCHR
;	JMP OUTCHR

OUTCHR:	TST OUTSW		;Who does it go to?
	BEQ 2$
1$:	TSTB KBOS		;VT05 ready?
	BPL 1$			;Loop til it is
	MOVB R0,KBOR		;Print the char
	RTS PC
2$:	TSTB OREG		;Console ready?
	BNE 2$			;Wait til it is
	MOVB R0,OREG		;Output char
	RTS PC

INCHR:	TST OUTSW		;Where does it come from?
	BEQ 1$
	TSTB KBIS		;Anything typed on VT05?
	BPL 2$			; No
	MOVB KBIR,R0		; Read the char
	RTS PC
1$:	TSTB IREG		;Anything from the 10?
	BEQ 2$			; No
	MOVB IREG,R0		; Fetch the char
	CLRB IREG
	RTS PC
2$:	CLR R0			;No input
	RTS PC

;Various Vision Module Messages


INIVIS:	.WORD 4,0,0	;Initialize communiations with Vision Module
RESTRT: .WORD 4,1,8.	;Soft Restart
PIC:	.WORD 2,2	;Take a picture
REPIC:	.WORD 2,3	;Reprocess the picture
GETFET:	.WORD 6,4,1,8.,0,0,0,0
BLINK:	.WORD 6,5,1,-1	;Blink blob
DLBLOB:	.WORD 4,6,1	;Delete blob
CALIB:	.WORD 4,7,1	;Calibrate
REMEM:	.WORD 12.,8.,7	;Create a new prototype (#=7)
	.ASCIZ /FOO/	;Named FOO
	.BLKW 10
RECOG:	.WORD 4,10,1	;Recognize blob
WHERE:	.WORD 8.,11.,1,9.,0	;Where are they all
SREAD:	.WORD 11.,13.	;Read switch value
	.ASCIZ /TRAINING/
	.BLKW 10
SWRITE:	.WORD 19.,14.,-1	;Set switch (off)
	.ASCIZ /KEEP-ALL-BLOBS/
	.BLKW 10
VREAD:	.WORD 24.,15.		;Read variable value
	.ASCIZ /IMAGE-PROCESSING-TIME/
	.BLKW 10
VWRITE:	.WORD 23.,16.		;Write variable value
	.FLT2 1.75
	.ASCIZ /CALIBRATION-SIZE/
	.BLKW 10
ERASE:	.WORD 4,24.,0		;Erase graphics overlay
CLEARW:	.WORD 12.,25.,0,0,100,20,0	;Clear an area
DRAW:	.WORD 12.,26.,0,0,20,100,-1	;Draw a vector
TEXT:	.WORD 13.,27.,0,0		;Display text
	.ASCIZ /Hello?/
	.BLKW 10

;Data & Constants

STATE:	0		;What we're doing:
			;  0 = nothing
			;  1 = waiting for ok to start sending
			;  2 = sending data & cksum
			;  3 = waiting for message received ok
			;  4 = receiving data & cksum
			;  5 = waiting for ok to continue
			;  6 = reset in progress

ADISP:	.WORD A0,A1,ABAD,A3,ABAD,ABAD,A6	;Req A dispatch table
BDISP:	.WORD B0,B1,B2,BBAD,B4,B5,BBAD	;Req B dispatch table

SBUF:	.BLKW 100	;Message to send
RBUF:	.BLKW 100	;Where we'll store the message

MESS:	SBUF		;Start of message to be sent
SPTR:	SBUF		;What to send next
SCNT:	0		;How much left to send
RPTR:	RBUF		;Where to store next word
RCNT:	0		;How much left to receive
CKSUM:	0

SDONE: 	.WORD 0		;Set when message has been sent
RDONE: 	.WORD 0		;Set when reply has been received

BEGMES:	.ASCII /πVision Module Communication Test Program/
CRLF:	.BYTE 12,15,0
RDYMES:	.ASCIZ /πReady to send./
TSNMES:	.ASCIZ /πTrying to Send . . ./
SNDMES:	.ASCIZ /πSending . . . /
TRCMES:	.ASCIZ /πReady to Receive . . ./
RCVMES: .ASCIZ /πReceiving . . ./
DONMES: .ASCIZ /πDone./

;Error messages

TIMMES:	.ASCIZ /πTime out on reset acknowledge./
RESMES:	.ASCIZ /πExternal reset./
NBFMES:	.ASCIZ /πNo available buffers in VM./
SBFMES:	.ASCIZ /πToo small buffer in VM./
ERRMES:	.ASCIZ /πUnknown error./
RSDMES:	.ASCIZ /πRe-Sending . . ./
RRCMES:	.ASCIZ /πRequesting retransmission . . ./
CHKMES:	.ASCIZ /πChecksum error./
ABDMES:	.ASCIZ /πUnexpected A Request./
BBDMES:	.ASCIZ /πUnexpected A Request./

.END START